# 用户相关的 授权相关的
from flask import Blueprint, render_template, jsonify, redirect, url_for, session    # redirect重定向，比如注册完成之后跳转到登录页面
from flask import request
from exts import mail, db
from flask_mail import Message
import string
import random
from models import EmailCaptchaModel
from .forms import RegisterForm, LoginForm   # forms前边的点表示同一目录下
from models import UserModel
from werkzeug.security import generate_password_hash, check_password_hash   # generate_password_hash给密码加密用的
                                                     # check_password_hash用来验证加密之后的密码和未加密的密码是否一致

bp = Blueprint('auth', __name__, url_prefix='/auth')
# 参数1:代表的是蓝图的名称
# 参数2:是模块名，一般设置为__name__，用于寻找模板文件和静态文件
# 参数3:URL前缀，以后访问这个蓝图的所有URL都必须加上/auth前缀

# 注册/登录
@bp.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else:
        # 登录的话也需要提交一个表单验证
        form = LoginForm(request.form)
        if form.validate():
            email = form.email.data
            password = form.password.data
            user = UserModel.query.filter_by(email=email).first()
            if not user:
                print("邮箱在数据库中不存在！")
                return redirect(url_for("auth.login"))
            if check_password_hash(user.password, password):
                # cookie:
                # cookie中不适合存储太多数据，只适合存储少量数据
                # cookie一般用来存放登录授权的东西
                # flask中的session，是经过加密以后存储在cookie中的
                session['user_id'] = user.id
                return redirect("/")
            else:
                print("密码错误")
                return redirect(url_for("auth.login"))
        else:
            print(form.errors)
            return redirect(url_for("auth.login"))


# 渲染   GET:从服务器上获取数据   POST:将客户端的数据提交给服务器
@bp.route('/register', methods=["GET", "POST"])
def register():
    if request.method == 'GET':
        # 验证用户提交的邮箱和验证码是否对应且正确
        # 表单验证:flask-wtf:wtforms
        return render_template("register.html")
    else:  # 走的post请求
        form = RegisterForm(request.form)
        # 在前端的输入框，也就是register.html中，都在form标签内，所以request.form可以获取到用户提交的数据
        if form.validate():
            email = form.email.data
            username = form.username.data
            password = form.password.data
            user = UserModel(email=email, username=username, password=generate_password_hash(password))       # generate_password_hash加密
            db.session.add(user)
            db.session.commit()
            return redirect(url_for("auth.login"))                #url_for("login")='/auth/login'
        else:
            print(form.errors)
            return redirect(url_for("auth.register"))


# bp.route:如果没有指定methods参数，默认就是GET请求
@bp.route("/captcha/email", methods=['GET'])
def get_email_captcha():
    # /captcha/email/<email>
    # /captcha/email?=xxx@qq.com
    email = request.args.get("email")
    # 验证码：随机四位数字
    # string.digits*4:0123456789012345678901234567890123456789
    source = string.digits*4
    captcha = random.sample(source, 4)  # sample就是采样的意思
    captcha = "".join(captcha)  # 0117
    message = Message(subject="知了传课注册验证码", recipients=[email], body=f"您的验证码是:{captcha}")
    mail.send(message)
    # memcached/redis方式存储验证码  存储在缓存中也就是内存
    # 用数据库表的方式存储  缺点数据库的数据是存储在硬盘中，提取和读取速度有点慢
    email_captcha = EmailCaptchaModel(email=email, captcha=captcha)
    db.session.add(email_captcha)
    db.session.commit()
    # RESful API格式
    # {code:200/400/500，message:"",date:{}}                                200正常400错误500错误
    return jsonify({"code": 200, "message": "", "data": None})

@bp.route("/logout")
def logout():
    session.clear()   # 清除浏览器cokkie中的session
    return redirect("/")




@bp.route("/mail/test")
def mail_test():
    message = Message(subject="邮箱测试", recipients=["zou19337770221@163.com"], body="这是一条测试邮件")
    # subject邮箱主题或者标题  recipients邮箱号   body发送内容
    mail.send(message)
    return "邮件发送成功"



















































